/*
 * Albareth - an action roleplaying game.
 * Copyright (C) 2008 Jens Anuth
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *   02110-1301, USA.
 * 
 * $Id: Item.java 48 2008-05-17 02:04:48Z jens464 $
*/
package albareth.core.entity;

import albareth.core.Game;
import albareth.core.GameMap;
import albareth.frontend.Tile;
import albareth.util.Location;
import frosch.util.Log;
import frosch.util.Task;

public class Item extends Entity implements Asset, Activatable, Cloneable
{
    private ItemContainer _container = null;
    
    //private boolean _activatable = false;
    private boolean _lockedDown = false;
    
    /** gets rendered on top of other stuff. */
    private boolean _upperLayer = false;
    
    private int _amount = 1;
    
    private boolean _blocking = false;
    private boolean _destroyable = false;
    private boolean _npcBlocking = false;
    private boolean _translucent = true;
    private boolean _stackable = false;
    private boolean _activatable = false;


    
    public Item(String name, Tile tile)
    {
        super(name, tile);
    }
    
    public Object clone() throws CloneNotSupportedException
    {
        Item clone = (Item)super.clone();
        clone.setOwner(null);
        return clone; 
    }

    public void enchant(int level)
    {
    }
    
    public boolean isMobile()
    {
        return false;
    }

    public boolean isBlocking()
    {
        return _blocking;
    }
    
    public void setBlocking(boolean blocking)
    {
        _blocking = blocking;
    }
    
    public boolean isNPCBlocking()
    {
        return _npcBlocking ;
    }
    
    public void setNPCBlocking(boolean npcBlocking)
    {
        _npcBlocking = npcBlocking;
    }
    
    public void moveTo(GameMap map, int x, int y)
    {
        //ensures nobody owns this item after it is dropped onto map.
        if (_container != null) {
            _container.removeItem(this);
            setOwner(null);
        }
        super.moveTo(map, x, y);

    }

    public final boolean steppedOn(Mobile src)
    {
        return onSteppedOn(src);
    }

    

    public boolean isTranslucent()
    {
        return _translucent ;
    }

    public void setTranslucent(boolean translucent)
    {
        _translucent = translucent;
    }


    public void setStackable(boolean b)
    {
        _stackable = b;
    }
    
    public boolean isStackable()
    {
        return _stackable ;
    }
    
    public boolean isStackableWith(Object other)
    {
        return false;
    }


    public int getAmount()
    {
        return _amount;
    }

    public void setAmount(int amount)
    {
        _amount = amount;
    }


    public final void consume()
    {
        consume(1);
    }

    /**
     * @param i the amount to consume.
     */
    public void consume(int i)
    {
        _amount -= i;
        
        //if amount reaches 0, remove either from map or from its container.
        if (_amount < 1) {
            remove();
        }        
    }
    
    public boolean isInGame()
    {
        return getOwner() != null || getLocation() != null;
    }

    
    public void remove()
    {
        if (!isInGame()) {
            Log.warn("Item to remove is not in game at all: " + getName());
            return;
        }
        
        if (_container != null) {
            _container.removeItem(this);
        } else if (getMap() != null) {
            getMap().removeEntity(this);
        }

    }
    
    public Location getLocation()
    {
        if (_container != null) {
            return _container.getLocation();
        } else {
            return super.getLocation();
        }
    }

    public AssetOwner getOwner()
    {
        return _container;
    }

    public void setOwner(ItemContainer cont)
    {
        _container = cont;
    }

    public boolean isLockedDown()
    {
        return _lockedDown;
    }

    public void setLockedDown(boolean lockedDown)
    {
        _lockedDown = lockedDown;
    }
    
    public boolean isEquipable()
    {
        return false;
    }

    public boolean isActivatable()
    {
        return _activatable;
    }

    public void setActivatable(boolean b)
    {
        _activatable = b;
    }

    public void setUpperLayer(boolean b)
    {
        _upperLayer = b;

    }

    public boolean isUpperLayer()
    {
        return _upperLayer;
    }

    public boolean isDestroyable()
    {
        return _destroyable;
    }

    public void setDestroyable(boolean destroyable)
    {
        _destroyable = destroyable;
    }
    
    public int takeDamage(int rawDamage, int damageType, Entity causer)
    {
        if (!isDestroyable()) {
            return 0;
        }
        
        if (!onDestroy(causer, damageType)) {
            return 0;
        }
        
        remove();

        return rawDamage;
    }

    protected boolean onSteppedOn(Mobile src)
    {
        return false;
    }
    
    
    protected boolean onDestroy(Entity causer, int damageType)
    {
        return false;
    }

    public final boolean activate(Mobile src)
    {
        return onActivate(src);
    }

    public boolean canActivate(Mobile user)
    {
        return isActivatable();
    }

    public int getCooldownDuration()
    {
        return 0;
    }

    public long getCooldownDurationLeft()
    {
        return 0;
    }

    public int getCooldownGroup()
    {
        return -1;
    }

    public boolean isActivated()
    {
        return false;
    }

    public boolean isReady()
    {
        return false;
    }

    protected boolean onActivate(Mobile src)
    {
        return true;
    }
    
    public void startTimer(int delay)
    {
        //TODO: implement repeating tasks
        Task task = new Task()
        {
            public boolean execute() {
                onTimer();
                return true;
            }
        };
        Game.getContext().scheduleTask(task, delay);
    }

    protected void onTimer()
    {
    }

    
    


}
